#include <iostream>
#include <string>
#include <omp.h>

int main(int argc, char *argv[])
{
    if (argc < 2) {
        std::cerr << "Usage: " << argv[0] << " <num_threads>" << std::endl;
        return 1;
    }

    std::cout << "Number of available threads: " << omp_get_num_procs() << std::endl;
    std::cout << "Number of threads: " << omp_get_max_threads() << std::endl;

    long long n = 0;
    try {
        n = std::stoll(argv[1]);
    } catch (const std::out_of_range& oor) {
        std::cerr << "Error: Number N is too large or too small.\n";
        return 1;
    } catch (const std::invalid_argument& ia) {
        std::cerr << "Error: Invalid number N provided.\n";
        return 1;
    }

    std::cout << "we will calculate the sum of 1 to " << n << std::endl;

    auto t0 = omp_get_wtime();

    long long s = 0LL;

    #pragma omp parallel for reduction(+:s)
    for (long long i = 1; i <= n; ++i) {
        s += i;
    }

    auto t1 = omp_get_wtime();

    std::cout << "sum = " << s << std::endl;
     std::cout << "Elapsed wall clock time: " << t1 - t0 << " seconds" << std::endl;

    return 0;
}